// author: Shelman
// description: 封装的一些公共常用接口

#include "Common.h"
#include <ostream>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstdint>
#include <iomanip>
#include <chrono>
#include <math.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif


/*****************************************************
 * 功能：获取YYYY-MM-ddTHH:mm:ssZ格式的时间格式
 * 返回值：
 *     std::string：YYYY-MM-ddTHH:mm:ssZ格式的系统当前时间信息
 * ***************************************************/
std::string getUtcFormatCurSystemTimeISO8601()
{
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();
    // 转换为时间戳
    auto time_t_now = std::chrono::system_clock::to_time_t(now);

    // 使用线程安全的时间函数
    std::tm utc_tm;
#ifdef _WIN32
    gmtime_s(&utc_tm, &time_t_now);
#else
    gmtime_r(&time_t_now, &utc_tm);
#endif

    // 创建一个 stringstream 用于格式化
    std::ostringstream oss;
    // 格式化为 ISO 8601 格式
    oss << std::put_time(&utc_tm, "%Y-%m-%dT%H:%M:%SZ");

    return oss.str();
}

/*****************************************************
 * 功能：获取YYYY-MM-dd HH:mm:ss.zzz格式的时间格式
 * 返回值：
 *     std::string：YYYY-MM-dd HH:mm:ss.zzz格式的系统当前时间信息
 * ***************************************************/
std::string getFormatCurSystemTime()
{
    time_t tloc;
    struct tm tm;
#ifdef _WIN32
    FILETIME ft;
    SYSTEMTIME st;
    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &ft);
    ULARGE_INTEGER uli;
    uli.LowPart = ft.dwLowDateTime;
    uli.HighPart = ft.dwHighDateTime;
    tloc = (uli.QuadPart - 116444736000000000LL) / 10000000LL;
    localtime_s(&tm, &tloc);
    // Windows 上模拟 gettimeofday
    struct timeval tv;
    GetSystemTime(&st);
    tv.tv_sec = tloc;
    tv.tv_usec = st.wMilliseconds * 1000;
#else
    struct timeval tv;
    time(&tloc);
    localtime_r(&tloc, &tm);
    gettimeofday(&tv, nullptr);
#endif

    char szTimeInfo[64] = {0};

#if 1
    char szTemp[32] = {0};
    strftime(szTemp, sizeof(szTemp), "%Y-%m-%d %H:%M:%S", &tm);
    snprintf(szTimeInfo, sizeof(szTimeInfo), "%s.%03ld", szTemp, tv.tv_usec / 1000);
#else
    snprintf(szTimeInfo, sizeof(szTimeInfo), "%04d-%02d-%02d %02d:%02d:%02d.%03ld"
             , tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday
             , tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec / 1000);
#endif

    return std::string(szTimeInfo);
}

/*****************************************************
 * 功能：比较两个double类型的数据是否相等
 * 输入参数：
 *      dVal1：数值1
 *      dVal2：数值2
 * 返回值：
 *      bool：比较结果，true -- 相等，false -- 不相等
 * ***************************************************/
bool isEqual(double dVal1, double dVal2)
{
    return (fabs(dVal1 - dVal2) < 1e-5) ? true : false;
}



